package com.yjha.lzmarathonsys.controller;

import cn.hutool.Hutool;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.yjha.lzmarathonsys.bean.TbUser;
import com.yjha.lzmarathonsys.service.TbUserService;
import com.yjha.lzmarathonsys.utils.JwtUtils;
import com.yjha.lzmarathonsys.utils.PasswordUtil;
import com.yjha.lzmarathonsys.utils.R;
import com.yjha.lzmarathonsys.utils.RedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

@CrossOrigin
@RestController
@Api(value = "后台授权管理",tags = "后台授权管理")
//@RequestMapping("/admin")
public class LoginController {
    @Autowired
    TbUserService service;

    @Autowired
    private DefaultKaptcha captchaProducer;

    @Autowired
    private RedisUtils redisUtil;

    // 登录
    @SneakyThrows
    @ApiOperation(value = "登录")
    @RequestMapping(value = "/login" ,method = RequestMethod.POST)
    public R login(@RequestParam(defaultValue = "")String account, @RequestParam(defaultValue = "")String password,@RequestParam(defaultValue = "") String code, HttpServletResponse response) {
        String key = "login:fail:" + account;
        int failCount = redisUtil.get(key) == null ? 0 : Integer.parseInt(String.valueOf(redisUtil.get(key)));
        if (failCount >= 5) {
            return R.error("账号已锁定，请10分钟后重试");
        }
       // 每次失败递增
        redisUtil.set(key, failCount + 1, 600); // 锁定10分钟

        if(StrUtil.isBlank(account)||StrUtil.isBlank(password) || StrUtil.isBlank(code)){
            return R.error("登录失败，登录信息不全");
        }

        if (!code.equals(redisUtil.get("verifyCode"))) return R.error("登录失败，登录信息不正确！");

        JSONObject jsonObject = new JSONObject();
        //查询账号是否存在
        TbUser user = service.getOne(new QueryWrapper<TbUser>().eq("useraccount",account));
        if (user == null){
            return R.error("登录失败，登录信息不正确！");
        }

        String encryption = PasswordUtil.encryption(password, user.getSalt(), 3);

        if (!encryption.equals(user.getPassword())) { // 直接对比明文与哈希
            redisUtil.set(key, failCount + 1, 600);
            return R.error("账号或密码错误");
        } else {
            redisUtil.del(key); // 登录成功清除失败计数
            String token = JwtUtils.createToken(user.getId().longValue());
            user.setSalt("");
            user.setPassword("");
            jsonObject.putOnce("token", token);
            jsonObject.putOnce("user",user);
            Cookie cookie = new Cookie("token", token);
            cookie.setPath("/");
            cookie.setHttpOnly(true);  // 阻止JavaScript访问
            response.addCookie(cookie);

            // 使用用户ID作为唯一标识
            redisUtil.set("user:token:" + user.getId(), token, JwtUtils.TOKEN_TIME);
            // 在登录成功分支中清除失败计数
            redisUtil.del("login:fail:" + account);
            return R.ok("登录成功").put("obj",jsonObject);

        }
    }


    @ApiOperation(value = "获取验证码")
    @GetMapping("/captcha")
    public void getVerificationCodePhoto(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        byte[] captchaOutputStream = null;
        ByteArrayOutputStream imgOutputStream = new ByteArrayOutputStream();
        try {
            //生成验证码
            String verifyCode = captchaProducer.createText();
            //验证码字符串保存到redis中
            redisUtil.set("verifyCode", verifyCode,180);
            BufferedImage challenge = captchaProducer.createImage(verifyCode);
            //设置写出图片的格式
            ImageIO.write(challenge, "jpg", imgOutputStream);
        } catch (IllegalArgumentException e) {
            httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        captchaOutputStream = imgOutputStream.toByteArray();
        httpServletResponse.setHeader("Cache-Control", "no-store");
        httpServletResponse.setHeader("Pragma", "no-cache");
        httpServletResponse.setDateHeader("Expires", 0);
        httpServletResponse.setContentType("image/jpeg");
        ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream();
        responseOutputStream.write(captchaOutputStream);
        responseOutputStream.flush();
        responseOutputStream.close();
    }
    /***
     * 这个请求需要验证token才能访问
     *
     * @author: qiaoyn
     * @date 2019/06/14
     * @return String 返回类型
     */
    @ApiOperation(value = "退出登录")
    @GetMapping("/logout")
    public R logout(HttpServletRequest request, HttpServletResponse response) {

        String token = JwtUtils.getTokenFromRequest(request);

        Long userId = null;
        try {
            userId = JwtUtils.getUID(token);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 删除 Redis 中的 Token
        redisUtil.del("user:token:" + userId);
        // 清除客户端 Cookie
        Cookie cookie = new Cookie("token", null);
        cookie.setMaxAge(0);
        cookie.setPath("/");
        response.addCookie(cookie);
        return R.ok("退出成功");
    }
}
